import { computed, defineComponent, Fragment, ref, type PropType } from 'vue'
import { Options, Placement } from '@popperjs/core'
import { type MenuOption } from './types'
import Tooltip from '../Tooltip/Tooltip.vue'
import RenderVNode from '../Common/RenderVNode'
import { type TooltipInstance } from '../Tooltip/types'

const Dropdown = defineComponent({
  name: 'VDropdown',
  props: {
    placement: {
      type: String as PropType<Placement>,
      default: 'bottom',
    },
    trigger: {
      type: String as PropType<'hover' | 'click'>,
      default: 'hover',
    },
    transition: {
      type: String as PropType<'fade' | 'none'>,
      default: 'fade',
    },
    openDelay: {
      type: Number,
      default: 0,
    },
    closeDelay: {
      type: Number,
      default: 0,
    },
    popperOptions: {
      type: Object as PropType<Partial<Options>>,
    },
    menuOptions: {
      type: Array as PropType<MenuOption[]>,
      required: true,
    },
    hideAfterClick: {
      type: Boolean,
      default: true,
    },
  },
  emits: ['visible-change', 'select'],
  setup(
    {
      trigger,
      placement,
      popperOptions,
      openDelay,
      closeDelay,
      menuOptions,
      hideAfterClick,
    },
    { slots, emit, expose }
  ) {
    const tooltipRef = ref<TooltipInstance | null>(null)
    const itemClick = (e: MenuOption) => {
      if (e.disabled) {
        return
      }
      emit('select', e)
      if (hideAfterClick) {
        tooltipRef.value?.hide && tooltipRef.value?.hide()
      }
    }
    const visibleChange = (e: boolean) => {
      emit('visible-change', e)
    }
    expose({
      show: () => tooltipRef.value?.show!(),
      hide: () => tooltipRef.value?.hide!(),
    })
    const options = computed(() => {
      return menuOptions.map((item) => {
        return (
          <Fragment key={item.key}>
            {item.divided && (
              <li role="separator" class="divided-placeholder" />
            )}
            <li
              class={{
                'v-dropdown__item': true,
                'is-disabled': item.disabled,
                'is-divided': item.divided,
              }}
              id={'dropdown-item-' + item.key}
              onClick={() => itemClick(item)}
            >
              <RenderVNode VNode={item.label} />
            </li>
          </Fragment>
        )
      })
    })

    return () => (
      <div class="v-dropdown">
        <Tooltip
          trigger={trigger}
          placement={placement}
          popper-options={popperOptions}
          open-delay={openDelay}
          close-delay={closeDelay}
          onVisibleChange={visibleChange}
          ref={tooltipRef}
        >
          {{
            default: () => slots.default && slots.default(),
            content: () => <ul class="v-dropdown__menu">{options.value}</ul>,
          }}
        </Tooltip>
      </div>
    )
  },
})

export default Dropdown
